import simplejson
import datetime
import decimal

class Encoder(simplejson.JSONEncoder):
    def default(self, o):
        if isinstance(o, datetime.datetime):
            return o.strftime('%m/%d/%Y %H:%M:%S')
        elif isinstance(o, datetime.date):
            return o.strftime('%m/%d/%Y')
        elif isinstance(o, datetime.time):
            return o.strftime('%H:%M:%S')
        elif isinstance(o, decimal.Decimal):
            return str(o)
        
        return simplejson.JSONEncoder.default(self, o)

def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
        allow_nan=True, cls=None, indent=None, separators=None,
        encoding='utf-8', default=None, **kw):
    if cls == None:
        cls = Encoder
    
    return simplejson.dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, encoding, default)
  
def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
        parse_int=None, parse_constant=None, **kw):
    return simplejson.loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant)

def json(func):
    '''Allows a function to be exposed to return a json result.'''
    def wrapper(*args, **kw):
        result = func(*args, **kw)
        return dumps(result)
    wrapper.__name__ = func.__name__
    wrapper.__dict__ = func.__dict__
    wrapper.__doc__ = func.__doc__
    wrapper.func = func
    wrapper.exposed = True
    return wrapper